﻿
namespace MVVMAppIDataErrorInfo.ViewModel
{
    using GalaSoft.MvvmLight;
    using System.ComponentModel;
    using GalaSoft.MvvmLight.Command;
    using System.Windows.Input;
    using System.Collections.ObjectModel;
    using System.Linq;

    public class MainViewModel 
        : ViewModelBase, IDataErrorInfo
    {
        #region Properties

        string _equipment = string.Empty;
        public string Equipment
        {
            get { return _equipment; }
            set
            {
                if (_equipment != value)
                {
                    _equipment = value;
                    RaisePropertyChanged("Equipment");
                }                
            }
        }

        bool _test = false;

        string _runningHours = string.Empty;
        public string RunningHours
        {
            get { return _runningHours; }
            set
            {
                if (_test)
                {
                    throw new System.Exception("test");
                }
                if (_runningHours != value)
                {
                    _runningHours = value;
                    RaisePropertyChanged("RunningHours");
                }                
            }
        }

        string _equipmentOperator = string.Empty;
        public string EquipmentOperator
        {
            get { return _equipmentOperator; }
            set
            {
                if (_equipmentOperator != value)
                {
                    _equipmentOperator = value;
                    RaisePropertyChanged("EquipmentOperator");
                    RaisePropertyChanged("ShiftSupervisor");
                }
            }
        }

        string _shiftSupervisor = string.Empty;
        public string ShiftSupervisor
        {
            get { return _shiftSupervisor; }
            set
            {
                if (_shiftSupervisor != value)
                {
                    _shiftSupervisor = value;
                    RaisePropertyChanged("ShiftSupervisor");
                    RaisePropertyChanged("EquipmentOperator");
                }
            }
        }

        ICommand _logRunningHoursCommand = null;
        public ICommand LogRunningHoursCommand
        {
            get
            {   
                if (_logRunningHoursCommand == null)
                {
                    _logRunningHoursCommand = new RelayCommand(
                                () =>
                                {
                                    UpdateState(StateOfView.Updated);

                                    Error = string.Join("",
                                        ValidationMessages
                                            .Select<ValidationError, string>
                                                (e => e.ErrorMessage)
                                            .ToArray<string>());
                                    
                                    if (!string.IsNullOrEmpty(Error))
                                    {
                                        //log running hours
                                    }
                                });
                }

                return _logRunningHoursCommand;
            }
        }

        ObservableCollection<ValidationError> _validationMessages;
        ObservableCollection<ValidationError> ValidationMessages
        {
            get
            {
                if (_validationMessages == null)
                {
                    _validationMessages = new ObservableCollection<ValidationError>() 
                            {
                                new ValidationError() 
                                   {PropertyName = "Equipment"},
                                new ValidationError() 
                                    {PropertyName = "RunningHours"},
                                new ValidationError()
                                    {PropertyName = "EquipmentOperator"},
                                new ValidationError()
                                    {PropertyName = "ShiftSupervisor"},
                                new ValidationError() 
                                    {PropertyName = "Generic"},
                            };
                }

                return _validationMessages;
            }
        }

        #endregion

        #region IDataErrorInfo implementation

        string _error = string.Empty;
        public string Error
        {
            get
            {
                return _error;
            }
            set
            {
                _error = value;
                RaisePropertyChanged("Error");
            }
        }

        public string this[string columnName]
        {
            get
            {
                string errorMessage = null;
                string propertyName = columnName;

                if (_state == StateOfView.Updated)
                {
                    object propertyValue =
                    this.GetType()
                        .GetProperty(propertyName)
                        .GetValue(this, null);

                    if (propertyValue == null ||
                        propertyValue.ToString()
                                     .Trim()
                                     .Equals(string.Empty))
                    {
                        errorMessage =
                            string.Format("{0} is required. ",
                            propertyName);
                    }
                }

                switch (columnName)
                {
                    case "EquipmentOperator":
                    case "ShiftSupervisor":
                        if (!EquipmentOperator.Equals(string.Empty) &&
                            EquipmentOperator.Equals(ShiftSupervisor))
                        {
                            errorMessage =
                              "Equipment operator and Shift Supervisor must be different. ";
                        }

                        propertyName = "Generic";

                        break;
                }

                ValidationMessages
                    .Where<ValidationError>(e => e.PropertyName == propertyName)
                    .First<ValidationError>().ErrorMessage = errorMessage;
                
                return errorMessage;
            }
        }

        #endregion        

        #region Private Methods

        private void RaisePropertyChanges()
        {
            RaisePropertyChanged("Equipment");
            RaisePropertyChanged("RunningHours");
            RaisePropertyChanged("EquipmentOperator");
            RaisePropertyChanged("ShiftSupervisor");

        }

        private void UpdateState(StateOfView state)
        {
            _state = state;
            RaisePropertyChanges();
        }
        #endregion
        
        #region Private Fields
        
        private StateOfView _state { get; set; }

        #endregion
    }
}
